package org.dromara.exam.consumer;

import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.redis.utils.QueueUtils;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.common.sse.utils.SseMessageUtils;
import org.dromara.exam.domain.dto.ScoreCalculatorTask;
import org.dromara.exam.domain.vo.ExamAnswerVo;
import org.dromara.exam.service.IExamAnswerService;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/**
 * @author xiyin321
 * @since 2025/5/20
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ScoreCalculatorConsumer {
    private final IExamAnswerService answerService;
    // 独立线程池
    private final Executor asyncExecutor = Executors.newFixedThreadPool(8);

    @PostConstruct
    public void init() {
        QueueUtils.subscribeBlockingQueue("exam:score:queue", this::processScoreTask, false);
        log.info("初始化分数计算队列消费者");
    }
    private CompletionStage<Void> processScoreTask(ScoreCalculatorTask task) {
        CompletableFuture.runAsync(() -> {
            try {
                ExamAnswerVo result = answerService.updateByBo(task.getBo());
                RedisUtils.setCacheObject(
                    "exam:score:status:" + task.getTaskId(),
                    result,
                    Duration.ofMinutes(600) // 根据需求调整过期时间
                );
//                SseMessageUtils.sendMessage(task.getUserId(), "分数计算完成");
            } catch (Exception e) {
                RedisUtils.setCacheObject(
                    "exam:score:status:" + task.getTaskId(),
                    "error:" + e.getMessage(),
                    Duration.ofMinutes(600)
                );
//                SseMessageUtils.sendMessage(task.getUserId(), "分数计算错误");
            }
        }, asyncExecutor);
        return CompletableFuture.completedFuture(null);
    }
}
